import os
import tkinter as tk
from tkinter import scrolledtext, messagebox
from subprocess import Popen, PIPE
import threading
import time
from Libs.logs.logs import get_logger

logger = get_logger(__name__)


class CommandLauncher(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("智慧大脑数据汇总监控系统")
        self.geometry("800x500")
        self.configure(bg='#f0f0f0')
        
        # 初始化变量
        self.python_location = None
        self.pip_location = None
        self.pid_file = "pid.pid"
        self.pid = None
        self.process = None
        
        # 创建UI组件
        self._create_widgets()
        
        # 启动状态检查
        self.check_run_status_label()
        
        # 初始化环境
        self.after(100, self._initialize_environment)

    def _create_widgets(self):
        """创建UI组件"""
        # 主框架
        main_frame = tk.Frame(self, bg='#f0f0f0')
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 标题
        title_label = tk.Label(main_frame, text="智慧大脑数据汇总监控系统", 
                              font=('Arial', 16, 'bold'), bg='#f0f0f0')
        title_label.pack(pady=(0, 10))
        
        # 日志显示区域
        log_frame = tk.Frame(main_frame)
        log_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
        
        self.text_area = scrolledtext.ScrolledText(
            log_frame, 
            wrap=tk.WORD, 
            width=80, 
            height=20,
            font=('Consolas', 9)
        )
        self.text_area.pack(fill=tk.BOTH, expand=True)
        
        # 按钮区域
        button_frame = tk.Frame(main_frame, bg='#f0f0f0')
        button_frame.pack(fill=tk.X, pady=(0, 10))
        
        # 启动按钮
        self.start_button = tk.Button(
            button_frame, 
            text="启动服务", 
            command=self.run_start_script,
            bg='#4CAF50',
            fg='white',
            font=('Arial', 10, 'bold'),
            width=12
        )
        self.start_button.pack(side=tk.LEFT, padx=(0, 10))
        
        # 停止按钮
        self.stop_button = tk.Button(
            button_frame, 
            text="停止服务", 
            command=self.run_stop_script,
            bg='#f44336',
            fg='white',
            font=('Arial', 10, 'bold'),
            width=12
        )
        self.stop_button.pack(side=tk.LEFT, padx=(0, 10))
        
        # 重启按钮
        self.restart_button = tk.Button(
            button_frame, 
            text="重启服务", 
            command=self.restart_service,
            bg='#2196F3',
            fg='white',
            font=('Arial', 10, 'bold'),
            width=12
        )
        self.restart_button.pack(side=tk.LEFT, padx=(0, 10))
        
        # GIT更新按钮
        self.git_button = tk.Button(
            button_frame, 
            text="GIT更新", 
            command=self.use_git_update,
            bg='#FF9800',
            fg='white',
            font=('Arial', 10, 'bold'),
            width=12
        )
        self.git_button.pack(side=tk.LEFT, padx=(0, 10))
        
        # 状态显示
        self.run_status_label = tk.Label(
            button_frame, 
            text="状态: 检查中...", 
            bg='#e0e0e0',
            font=('Arial', 10),
            relief=tk.SUNKEN,
            padx=10
        )
        self.run_status_label.pack(side=tk.RIGHT)

    def _initialize_environment(self):
        """初始化环境"""
        try:
            self.check_python_location()
            self.check_requirements()
        except Exception as e:
            self.text_area_print(f"环境初始化失败: {e}")
            logger.error(f"环境初始化失败: {e}")

    def text_area_print(self, text):
        """在文本区域打印信息"""
        timestamp = time.strftime("%H:%M:%S")
        self.text_area.insert(tk.END, f"[{timestamp}] {text}\n")
        self.text_area.see(tk.END)
        self.update_idletasks()

    def check_run_status_label(self):
        """检查运行状态并更新标签"""
        self.check_run_status()
        if self.pid:
            status = f"状态: 运行中 (PID: {self.pid})"
            self.run_status_label.config(bg='#4CAF50', fg='white')
            self.start_button.config(state=tk.DISABLED)
            self.stop_button.config(state=tk.NORMAL)
        else:
            status = "状态: 未运行"
            self.run_status_label.config(bg='#f44336', fg='white')
            self.start_button.config(state=tk.NORMAL)
            self.stop_button.config(state=tk.DISABLED)
        
        self.run_status_label.config(text=status)
        self.after(2000, self.check_run_status_label)  # 每2秒检查一次

    def check_python_location(self):
        """检查Python环境"""
        run_path = os.getcwd()
        if os.path.exists("venv/Scripts/pythonw.exe"):
            self.python_location = os.path.join(run_path, r"venv\Scripts\pythonw.exe")
        else:
            self.python_location = "pythonw"
        
        if os.path.exists("venv/Scripts/pip.exe"):
            self.pip_location = os.path.join(run_path, r"venv\Scripts\pip.exe")
        else:
            self.pip_location = "pip"
        
        self.text_area_print(f"Python路径: {self.python_location}")
        self.text_area_print(f"Pip路径: {self.pip_location}")

    def check_run_status(self):
        """检查运行状态"""
        if os.path.exists(self.pid_file):
            try:
                with open(self.pid_file, "r") as f:
                    self.pid = f.read().strip()
                # 验证进程是否真的在运行
                if not self._is_process_running(self.pid):
                    self.pid = None
                    os.remove(self.pid_file)
            except Exception as e:
                logger.error(f"读取PID文件失败: {e}")
                self.pid = None
        else:
            self.pid = None

    def _is_process_running(self, pid):
        """检查进程是否在运行"""
        try:
            os.kill(int(pid), 0)
            return True
        except (OSError, ValueError):
            return False

    @staticmethod
    def decode_str(tmp_str):
        """解码字符串"""
        try:
            return tmp_str.decode("utf-8")
        except UnicodeDecodeError:
            try:
                return tmp_str.decode("gbk")
            except UnicodeDecodeError:
                return "无法解析返回结果！"

    def run_cmd(self, cmd_str, need_return_info=True):
        """执行命令"""
        self.text_area_print(f"执行命令: {cmd_str}")
        
        try:
            proc = Popen(cmd_str, shell=True, stdout=PIPE, stderr=PIPE)
            if need_return_info:
                stdout, stderr = proc.communicate()
                if stderr:
                    error_msg = self.decode_str(stderr)
                    self.text_area_print(f"错误: {error_msg}")
                    return False
                output = self.decode_str(stdout)
                if output.strip():
                    self.text_area_print(output)
                return True
            else:
                return True
        except Exception as e:
            self.text_area_print(f"命令执行失败: {e}")
            return False

    def check_requirements(self):
        """检查并安装依赖"""
        self.text_area_print("检查依赖包...")
        check_cmd = f"{self.pip_location} install -r requirements.txt -i http://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn"
        if self.run_cmd(check_cmd):
            self.text_area_print("依赖安装成功")
        else:
            self.text_area_print("依赖安装失败")

    def run_start_script(self):
        """启动脚本"""
        if self.pid:
            messagebox.showwarning("警告", "服务已在运行中！")
            return
        
        self.text_area_print("正在启动服务...")
        run_cmd = f"{self.python_location} run_script.py"
        if self.run_cmd(run_cmd, need_return_info=False):
            self.text_area_print("服务启动命令已执行")
        else:
            self.text_area_print("服务启动失败")

    def run_stop_script(self):
        """停止脚本"""
        if not self.pid:
            messagebox.showwarning("警告", "服务未在运行！")
            return
        
        self.text_area_print("正在停止服务...")
        run_cmd = f"taskkill /F /PID {self.pid}"
        if self.run_cmd(run_cmd):
            self.text_area_print("服务停止成功")
            if os.path.exists(self.pid_file):
                os.remove(self.pid_file)
        else:
            self.text_area_print("服务停止失败")

    def restart_service(self):
        """重启服务"""
        if self.pid:
            self.run_stop_script()
            time.sleep(2)  # 等待进程完全停止
        self.run_start_script()

    def use_git_update(self):
        """GIT更新"""
        self.text_area_print("正在更新代码...")
        run_cmd = "git pull"
        if self.run_cmd(run_cmd):
            self.text_area_print("代码更新成功")
        else:
            self.text_area_print("代码更新失败")


if __name__ == "__main__":
    try:
        app = CommandLauncher()
        app.mainloop()
    except Exception as e:
        logger.error(f"启动器运行失败: {e}")
        print(f"启动器运行失败: {e}")
